home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
program
/
wil4c10.zip
/
FTP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-07-26
|
31KB
|
933 lines
/*
** FTP.C
**
** FTP client, uses ASYNC functions.
**
** NOTE: The order of the FTP_* messages in message.h should match
** the order in FTP.RC.
*/
#include <windows.h>
#include <winsock.h>
#include "wil.h"
#include "about.h"
#include "async.h"
#include "message.h"
#include "paint.h"
#include "readini.h"
#include "str.h"
#ifdef WIN32
#define USE_INS HINSTANCE
#define USE_PTR PSTR
#else
#define USE_INS HANDLE
#define USE_PTR LPSTR
#endif
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
/* globals */
HWND hMainWnd; /* main window handle */
#define BS 8
#define LF 10
#define CR 13
#define ESC 27
#define MAX_BUF 512
#define MAX_STR 50
#define HALF_SEC 500
#define ONE_SEC 1000
#define TWO_SEC 2000
#define FIVE_SEC 5000
#define TEN_SEC 10000
#define FTP_PORT 21
#define FIRST_DATA_PORT 6145
#define LAST_DATA_PORT 6175
#define FTP_CONN_SUCCESS 101
#define FTP_CONN_FAILURE 102
#define FTP_USER_SUCCESS 103
#define FTP_PASS_SUCCESS 104
#define FTP_CMD_SUCCESS 201
#define FTP_CMD_FAILURE 202
#define FTP_QUIT_SUCCESS 203
#define FTP_LIST_BEGIN 301
#define FTP_LIST_SUCCESS 302
#define FTP_LIST_READY 303
#define FTP_LIST_INCOMING 304
#define FTP_GET_BEGIN 401
#define FTP_GET_SUCCESS 402
#define FTP_GET_READY 403
#define FTP_GET_INCOMING 404
#define FTP_PUT_BEGIN 501
#define FTP_PUT_SUCCESS 502
#define FTP_PUT_READY 503
#define FTP_PUT_SENDING 504
static USE_INS hInstance;
static int WinWidth = 8 * NCOLS; /* window width */
static int WinHeight = 15 * NROWS; /* window height */
static char Temp[MAX_BUF+8]; /* temporary buffer */
static int InBufCmd = 0; /* command */
static int InBufLen = 0; /* length of string in InBuffer[] */
static char InBuffer[MAX_BUF+1]; /* buffer for input */
static SOCKET ControlSock = 0; /* control socket */
static SOCKET ListenSock = 0; /* listen socket */
static SOCKET DataSock = 0; /* data socket */
static ULONG MyHostAddr = 0; /* address of local host */
static char MyDottedAddr[17]; /* dotted notation of <MyHostAddr> */
static int ConnectedFlag = 0; /* connected to FTP server if TRUE */
static short DataPort = FIRST_DATA_PORT; /* data port number */
static int FileHandle = 0; /* file handle */
static char Filename[256] = "\0"; /* filename buffer */
static long RxBytes; /* # bytes received */
static long TxBytes; /* # bytes transmitted */
static HCURSOR ArrowCursor; /* arrow cursor */
static HCURSOR WaitCursor; /* hour glass cursor */
static char UserString[MAX_STR] = "";/* user login name */
static char PassString[MAX_STR] = "";/* user login password */
static DWORD ListenerTimeMark = 0; /* system timer time mark */
static int Want2Tx; /* bytes want to send */
/* put cursor in window */
static void SetTheFocus(void)
{/* create client area caret */
CreateCaret(hMainWnd,NULL,3,10);
SetCaretPos(PaintGetColPos(),PaintGetRowPos());
ShowCaret(hMainWnd);
}
/* disable range of menu items */
static void DisableMenuItems(int First, int Last)
{int i;
HMENU hMenu;
hMenu = GetMenu(hMainWnd);
for(i=First;i<=Last;i++)
EnableMenuItem(hMenu,i,MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
DrawMenuBar(hMainWnd);
}
/* enable range of menu items */
static void EnableMenuItems(int First, int Last)
{int i;
HMENU hMenu;
hMenu = GetMenu(hMainWnd);
for(i=First;i<=Last;i++)
EnableMenuItem(hMenu,i,MF_BYCOMMAND | MF_ENABLED);
DrawMenuBar(hMainWnd);
}
/* menu state when not connected, awaiting user input */
void NotConnectedMenuState(void)
{EnableMenuItems(MSG_FTP_CONNECT, MSG_FTP_CONNECT);
DisableMenuItems(MSG_FTP_CWD, MSG_FTP_QUIT);
}
/* menu state when connected, awaiting user input */
void ConnectedMenuState(void)
{DisableMenuItems(MSG_FTP_CONNECT, MSG_FTP_CONNECT);
EnableMenuItems(MSG_FTP_CWD, MSG_FTP_QUIT);
}
/* menu state while executing FTP command */
void DoingCmdMenuState(void)
{DisableMenuItems(MSG_FTP_CONNECT, MSG_FTP_QUIT);
}
/* display error text */
static void DisplayError(int Code, LPSTR Msg)
{wsprintf((LPSTR)Temp, "ERROR %d:", Code);
DisplayString((LPSTR)Temp);
if(Msg) DisplayString(Msg);
if(Code)
{wilErrorText(Code,(LPSTR)Temp,50);
DisplayLine((LPSTR)Temp);
}
SetCursor(ArrowCursor);
}
/* add character to input buffer */
static void Add2Buffer(char Chr)
{int i;
/* add char to input buffer */
switch(Chr)
{case BS:
if(InBufLen>0)
{/* backup on screen */
DisplayChar(BS);
/* remove last char from buffer */
InBufLen--;
}
break;
case ESC:
for(i=1;i<=InBufLen;i++) DisplayChar(BS);
InBufLen = 0;
DestroyCaret();
break;
default:
/* display char */
DisplayChar(Chr);
/* put into buffer */
if(InBufLen<MAX_BUF) InBuffer[InBufLen++] = Chr;
break;
}
}
/* display socket status */
static void CheckSocket(LPSTR Msg, SOCKET Socket)
{int Read = wilSocketStatus(Socket,WIL_READ_STATUS);
int Write = wilSocketStatus(Socket,WIL_WRITE_STATUS);
int Error = wilSocketStatus(Socket,WIL_ERROR_STATUS);
wsprintf((LPSTR)Temp,"%s %d R:%d W:%d E:%d",Msg,Socket,Read,Write,Error);
DisplayLine((LPSTR)Temp);
}
/* still connected ? */
static int StillConnected(void)
{if(wilIsConnected(ControlSock,0)) return TRUE;
DisplayLine("Connection to FTP host lost");
return FALSE;
}
/* accept data connection */
static int FtpAccept(void)
{
DataSock = wilAccept(ListenSock,(long)ONE_SEC);
if((int)DataSock<0)
{DisplayError((int)DataSock, "Accept:");
return FALSE;
}
DisplayLine("Connection is accepted");
return TRUE;
}
/* set up listener socket */
static int FtpListen(void)
{int Code;
/* set up listener socket */
ListenSock = wilTcpSocket();
if((int)ListenSock<=0)
{DisplayError((int)ListenSock, "wilListen:");
return FALSE;
}
/* bind port address to socket */
wsprintf((LPSTR)Temp,"Binding %s to port %d",(LPSTR)MyDottedAddr, DataPort);
DisplayLine((LPSTR)Temp);
Code = wilBind(ListenSock, MyHostAddr, DataPort);
if(Code<0)
{DisplayError((int)Code, "wilBind:");
return FALSE;
}
/* listen for connection attempt */
Code = wilListen(ListenSock,1);
if(Code<0)
{DisplayError(Code, "wilListen:");
return FALSE;
}
return TRUE;
}
/* get any outstanding incoming data from control socket */
static void GetControlIncoming(void)
{int Code;
/* any more control socket response ? */
while(wilDataIsReady(ControlSock,0))
{Code = wilReadString(ControlSock,(LPSTR)InBuffer,MAX_BUF);
if(Code<=0) break;
DisplayString((LPSTR)InBuffer);
}
}
/* find local socket address */
ULONG GetAddrFromSock(SOCKET Socket, LPSTR DottedAddr)
{ULONG HostAddr;
/* get address from socket */
HostAddr = wilLocalSockAddr(Socket);
wsprintf((LPSTR)DottedAddr,"%1ld.%1ld.%1ld.%1ld",
0x000000ff & (HostAddr>>24),
0x000000ff & (HostAddr>>16),
0x000000ff & (HostAddr>>8),
0x000000ff & (HostAddr) );
wsprintf((LPSTR)Temp,"LocalSockAddr = %s (%lx) ",
(LPSTR)DottedAddr, HostAddr);
DisplayLine((LPSTR)Temp);
return HostAddr;
}
/* WinMain */
#ifdef WIN32
int WINAPI
#else
int PASCAL
#endif
WinMain(USE_INS hInst, USE_INS hPrevInstance,
USE_PTR szCmdLine, int nCmdShow)
{WNDCLASS wc;
MSG msg;
BOOL Result;
if(!hPrevInstance)
{/* register main window class */
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = LoadIcon(hInst, "HostIcon");
wc.hCursor = NULL;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = "HostMenu";
wc.lpszClassName = "HostWClass";
Result = RegisterClass(&wc);
if(!Result) return FALSE;
}
/* create main window */
hInstance = hInst;
hMainWnd = CreateWindow(
"HostWClass", "FTP", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
WinWidth, WinHeight,
NULL, NULL,
hInstance, NULL);
ShowWindow(hMainWnd, nCmdShow);
UpdateWindow(hMainWnd);
/* window control loop */
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (msg.wParam);
} /* end WinMain */
#ifdef WIN32
LRESULT CALLBACK
#else
long FAR PASCAL
#endif
MainWndProc(HWND hWindow,UINT iMsg,WPARAM wParam,LPARAM lParam)
{int Code;
HDC hDC;
PAINTSTRUCT ps;
int i;
LPSTR Ptr;
#ifdef WIN32
#else
static FARPROC lpfnAboutDlgProc;
#endif
/* begin */
hMainWnd = hWindow;
switch (iMsg)
{case WM_CREATE:
/* create cursors */
ArrowCursor = LoadCursor(NULL, IDC_ARROW);
WaitCursor = LoadCursor(NULL, IDC_WAIT);
SetCursor(ArrowCursor);
#ifdef WIN32
#else
/* create thunk for Win16 */
lpfnAboutDlgProc = MakeProcInstance(AboutDlgProc,hInstance);
#endif
/* initialize paint module */
PaintInit();
/* attach WINSOCK */
DisplayString("Attaching WINSOCK...");
Code = wilAttach();
DisplayLine("OK");
if(Code<0) DisplayError(Code,"wilAttach fails:");
else
{wsprintf((LPSTR)Temp," Description: %s", wilGetDescription() );
DisplayLine((LPSTR)Temp);
wsprintf((LPSTR)Temp," My HostName: %s", wilGetMyHostName() );
DisplayLine((LPSTR)Temp);
Ptr = (LPSTR) wilGetMyHostDotted(0);
wsprintf((LPSTR)Temp," My HostAddr: %s", Ptr );
DisplayLine((LPSTR)Temp);
lstrcpy((LPSTR)MyDottedAddr, (LPSTR)Ptr);
MyHostAddr = wilGetMyHostAddr(0);
}
NotConnectedMenuState();
*InBuffer = '\0';
*Temp = '\0';
/* open FTP.INI file */
if(!IniOpen("FTP.INI")) break;
DisplayLine("FTP.INI opened");
while(1)
{/* read next line from FTP.INI */
if(IniRead((LPSTR)Temp)<0) break;
DisplayLine((LPSTR)Temp);
/* test for all legal keywords */
IniExtract((LPSTR)Temp,"USER",(LPSTR)UserString);
IniExtract((LPSTR)Temp,"PASS",(LPSTR)PassString);
}
#if 0
/* echo login name & password */
wsprintf((LPSTR)Temp,"UserString=[%s]",(LPSTR)UserString);
DisplayLine((LPSTR)Temp);
wsprintf((LPSTR)Temp,"PassString=[%s]",(LPSTR)PassString);
DisplayLine((LPSTR)Temp);
#endif
/* verify that we have login name & password */
if(lstrlen((LPSTR)UserString)==0) DisplayLine("ERROR: Missing FTP login user name.");
if(lstrlen((LPSTR)PassString)==0) DisplayLine("ERROR: Missing FTP login password.");
break;
case WM_COMMAND:
switch(wParam)
{case MSG_ABOUT:
#ifdef WIN32
DialogBox(hInstance, "AboutBox", hMainWnd, AboutDlgProc);
#else
DialogBox(hInstance, "AboutBox", hMainWnd, lpfnAboutDlgProc);
#endif
return 0;
case MSG_BREAK:
wilCancelBlocking();
if(ConnectedFlag) ConnectedMenuState();
else NotConnectedMenuState();
/* anything in control sock ? */
GetControlIncoming();
DataPort++;
break;
case MSG_EXIT:
/* close all sockets & exit */
if(ControlSock) wilCloseSocket(ControlSock);
if(ListenSock) wilCloseSocket(ListenSock);
if(DataSock) wilCloseSocket(DataSock);
wilRelease();
DestroyWindow(hMainWnd);
break;
case MSG_DEBUG:
CheckSocket("ControlSock", ControlSock);
if(ListenSock) CheckSocket("ListenSock", ListenSock);
if(DataSock) CheckSocket("DataSock", DataSock);
*InBuffer = '\0';
break;
case MSG_FTP_CONNECT:
/* connect to remote host */
InBufLen = 0;
InBufCmd = MSG_FTP_CONNECT;
DisplayString("Enter FTP address:");
SetTheFocus();
DoingCmdMenuState();
break;
case MSG_FTP_QUIT:
/* quit FTP session */
if(!StillConnected()) break;
DoingCmdMenuState();
AsyncCommand("QUIT", FTP_QUIT_SUCCESS, FTP_CMD_FAILURE,
ASYNC_MULTIPLE_CODED);
ConnectedFlag = 0;
break;
case MSG_FTP_CWD:
/* change working directory */
InBufLen = 0;
InBufCmd = MSG_FTP_CWD;
DisplayString("Enter directory:");
SetTheFocus();
DoingCmdMenuState();
break;
case MSG_FTP_BINARY:
/* set binary transfer mode */
if(!StillConnected()) break;
DoingCmdMenuState();
AsyncCommand("TYPE I", FTP_CMD_SUCCESS, FTP_CMD_FAILURE,
ASYNC_MULTIPLE_CODED);
break;
case MSG_FTP_ASCII:
/* set ascii transfer mode */
if(!StillConnected()) break;
DoingCmdMenuState();
AsyncCommand("TYPE A", FTP_CMD_SUCCESS, FTP_CMD_FAILURE,
ASYNC_MULTIPLE_CODED);
break;
case MSG_FTP_LIST:
/* list files */
if(!StillConnected()) break;
DoingCmdMenuState();
/* transmit PORT command */
wsprintf((LPSTR)Temp,"PORT %s,%1d,%1d", (LPSTR)MyDottedAddr,
(DataPort>>8), (0x00ff&DataPort) );
/* replace dots with commas in PORT command */
for(i=5;i<=16;i++) if(Temp[i]=='.') Temp[i] = ',';
AsyncCommand((LPSTR)Temp, FTP_LIST_SUCCESS, FTP_CMD_FAILURE,
ASYNC_MULTIPLE_CODED);
break;
case MSG_FTP_GET:
/* get (receive) file */
if(!StillConnected()) break;
DoingCmdMenuState();
InBufLen = 0;
InBufCmd = MSG_FTP_GET;
DisplayString("Enter filename to receive:");
SetTheFocus();
DoingCmdMenuState();
break;
case MSG_FTP_PUT:
/* put (send) file */
if(!StillConnected()) break;
InBufLen = 0;
InBufCmd = MSG_FTP_PUT;
DisplayString("Enter filename to send:");
SetTheFocus();
DoingCmdMenuState();
break;
}
break;
case WM_PAINT:
HideCaret(hMainWnd);
hDC = BeginPaint(hMainWnd, &ps);
SetMapMode(hDC,MM_ANISOTROPIC);
SelectObject(hDC, GetStockObject(OEM_FIXED_FONT) );
PaintMain(hDC,&ps);
EndPaint(hMainWnd,&ps);
SetCaretPos(PaintGetColPos(),PaintGetRowPos());
ShowCaret(hMainWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_USER: /* posted by WIL */
AsyncProcessMsg(lParam);
break;
case WM_USER+1: /* posted by Async functions */
/* get response code */
if(lParam>=500)
{/* FTP server returns fatal error code */
POST_MSG(FTP_CMD_FAILURE);
break;
}
/* execute case */
switch(wParam)
{
case FTP_CONN_SUCCESS:
/* we are now connected. log on to server */
DisplayLine("Connected to FTP server. Logging on...");
wsprintf((LPSTR)Temp,"USER %s",(LPSTR)UserString);
AsyncCommand((LPSTR)Temp, FTP_USER_SUCCESS, FTP_CONN_FAILURE,
ASYNC_MULTIPLE_CODED);
break;
case FTP_USER_SUCCESS:
/* USER command was successful */
wsprintf((LPSTR)Temp,"PASS %s",(LPSTR)PassString);
AsyncCommand((LPSTR)Temp, FTP_PASS_SUCCESS, FTP_CONN_FAILURE,
ASYNC_MULTIPLE_CODED);
break;
case FTP_PASS_SUCCESS:
/* PASS command was successful */
ConnectedFlag = TRUE;
DisplayLine("Logged on to FTP server.");
ConnectedMenuState();
SetCursor(ArrowCursor);
break;
case FTP_CONN_FAILURE:
/* FTP connection has failed */
DisplayLine("Cannot CONNECT");
NotConnectedMenuState();
SetCursor(ArrowCursor);
break;
/*** QUIT command ***/
case FTP_QUIT_SUCCESS:
/* QUIT command was successful */
ConnectedFlag = TRUE;
NotConnectedMenuState();
SetCursor(ArrowCursor);
break;
case FTP_CMD_SUCCESS:
/* FTP command was successful */
ConnectedMenuState();
DisplayLine("FTP command succeeds.");
SetCursor(ArrowCursor);
break;
case FTP_CMD_FAILURE:
/* FTP command has failed */
DisplayLine("FTP command fails...");
ConnectedMenuState();
SetCursor(ArrowCursor);
break;
/*** LIST command (from case ) ***/
case FTP_LIST_SUCCESS:
/* PORT command was successful */
if(!FtpListen()) break;
/* ask server to send list of files */
ListenerTimeMark = GetCurrentTime() + TEN_SEC;
AsyncCommand("LIST", FTP_LIST_READY, FTP_CMD_FAILURE,
ASYNC_MULTIPLE_CODED);
break;
case FTP_LIST_READY:
/* LIST command was successful */
if(GetCurrentTime() > ListenerTimeMark)
{/* where's the data ? */
DisplayLine("Listener socket is silent . . .");
wilCloseSocket(ListenSock);
POST_MSG(FTP_CMD_FAILURE);
break;
}
/* any incoming on listener socket ? */
if(wilDataIsReady(ListenSock,500))
{/* accept connection [get DataSock] */
FtpAccept();
POST_MSG(FTP_LIST_INCOMING);
}
else
{/* nothing on data socket yet */
POST_MSG(FTP_LIST_READY);
}
break;
case FTP_LIST_INCOMING:
DisplayLine("Reading data from data socket...");
/* data socket has data */
while(1)
{/* read next line from server */
if(!wilDataIsReady(DataSock,750)) break;
Code = wilReadLine(DataSock,(LPSTR)InBuffer,MAX_BUF);
if(Code<=0) break;
/* display data just read */
DisplayString((LPSTR)InBuffer);
}
*InBuffer = '\0';
DisplayLine("[END]");
/* close listener & data socket */
wilCloseSocket(DataSock);
wilCloseSocket(ListenSock);
if(++DataPort>LAST_DATA_PORT) DataPort = FIRST_DATA_PORT;
/* any more control socket response ? */
GetControlIncoming();
POST_MSG(FTP_CMD_SUCCESS);
break;
/*** GET command ***/
case FTP_GET_BEGIN:
/* issue PORT command */
wsprintf((LPSTR)Temp,"PORT %s,%1d,%1d", (LPSTR)MyDottedAddr,
(DataPort>>8), (0x00ff&DataPort) );
/* replace dots with commas in PORT command */
for(i=5;i<=16;i++) if(Temp[i]=='.') Temp[i] = ',';
AsyncCommand((LPSTR)Temp, FTP_GET_SUCCESS, FTP_CMD_FAILURE,
ASYNC_MULTIPLE_CODED);
break;
case FTP_GET_SUCCESS:
/* PORT command was successful, ask server to send file */
if(!FtpListen()) break;
wsprintf((LPSTR)Temp,"RETR %s",(LPSTR)Filename);
ListenerTimeMark = GetCurrentTime() + TEN_SEC;
AsyncCommand((LPSTR)Temp, FTP_GET_READY, FTP_CMD_FAILURE,
ASYNC_MULTIPLE_CODED);
break;
case FTP_GET_READY:
/* RETR command was successful */
if(GetCurrentTime() > ListenerTimeMark)
{/* where's the data ? */
DisplayLine("Listener socket is silent . . .");
wilCloseSocket(ListenSock);
POST_MSG(FTP_CMD_FAILURE);
break;
}
/* any incoming on listener socket ? */
if(wilDataIsReady(ListenSock,0))
{/* accept connection [get DataSock] */
FtpAccept();
/* any control socket response ? */
GetControlIncoming();
DisplayLine("Reading data from data socket...");
/* receive data on DataSock */
RxBytes = 0;
POST_MSG(FTP_GET_INCOMING);
}
else POST_MSG(FTP_GET_READY);
break;
case FTP_GET_INCOMING:
/* get incoming data */
while(1)
{/* get next buffer */
Code = wilReadSocket(DataSock,(LPSTR)InBuffer, MAX_BUF);
if(Code==0)
{/* socket open, but no data is ready */
POST_MSG(FTP_GET_INCOMING);
break;
}
if(Code==WIL_EOF)
{/* no more data */
wsprintf((LPSTR)Temp,"[EOF] %ld bytes received", RxBytes);
DisplayLine((LPSTR)Temp);
_lclose(FileHandle);
/* close listener & data socket */
wilCloseSocket(DataSock);
wilCloseSocket(ListenSock);
if(++DataPort>LAST_DATA_PORT) DataPort = FIRST_DATA_PORT;
/* any more control socket response ? */
GetControlIncoming();
/* we're done */
MessageBeep(MB_ICONEXCLAMATION);
POST_MSG(FTP_CMD_SUCCESS);
break;
}
if(Code<0)
{DisplayError(Code, "DataRead");
break;
}
/* Code > 0, so count received bytes */
RxBytes += (long)Code;
wsprintf((LPSTR)Temp,"%ld\r",RxBytes);
DisplayString((LPSTR)Temp);
/* save buffer to disk */
Code = _lwrite(FileHandle,(LPSTR)InBuffer,Code);
if(Code<0)
{wsprintf((LPSTR)Temp,"Error %d returned writing to %s",
Code, Filename);
DisplayLine((LPSTR)Temp);
_lclose(FileHandle);
break;
}
}
break;
/*** PUT command ***/
case FTP_PUT_BEGIN:
/* issue PORT command */
wsprintf((LPSTR)Temp,"PORT %s,%1d,%1d", (LPSTR)MyDottedAddr,
(DataPort>>8), (0x00ff&DataPort) );
/* replace dots with commas in PORT command */
for(i=5;i<=16;i++) if(Temp[i]=='.') Temp[i] = ',';
AsyncCommand((LPSTR)Temp, FTP_PUT_SUCCESS, FTP_CMD_FAILURE,
ASYNC_MULTIPLE_CODED);
break;
case FTP_PUT_SUCCESS:
/* PORT command was successful, ask server to receive file */
if(!FtpListen()) break;
wsprintf((LPSTR)Temp,"STOR %s",(LPSTR)Filename);
ListenerTimeMark = GetCurrentTime() + TWO_SEC;
AsyncCommand((LPSTR)Temp, FTP_PUT_READY, FTP_CMD_FAILURE,
ASYNC_MULTIPLE_CODED);
break;
case FTP_PUT_READY:
/* STOR command was successful */
if(GetCurrentTime() > ListenerTimeMark)
{/* where's the data ? */
DisplayLine("Listener socket is silent . . .");
wilCloseSocket(ListenSock);
POST_MSG(FTP_CMD_FAILURE);
break;
}
/* any incoming on listener socket ? */
if(wilDataIsReady(ListenSock,0))
{/* accept connection [get DataSock] */
if(FtpAccept()) POST_MSG(FTP_PUT_SENDING);
}
else POST_MSG(FTP_PUT_READY);
break;
case FTP_PUT_SENDING:
/* send data */
TxBytes = 0;
while(1)
{/* read from disk */
Code = _lread(FileHandle,(LPSTR)InBuffer,MAX_BUF);
if(Code<0)
{wsprintf((LPSTR)Temp,"Error %d returned reading from %s",
Code, Filename);
DisplayLine((LPSTR)Temp);
_lclose(FileHandle);
break;
}
if(Code==0) break;
/* Code>0: write to socket */
Want2Tx = Code;
Ptr = (LPSTR) InBuffer;
/* write all of data to socket */
while(Want2Tx > 0)
{if(!StillConnected()) break;
Code = wilWriteSocket(DataSock, Ptr, Want2Tx);
if(Code==0) break;
if(Code==WIL_EOF) break;
if(Code<0)
{DisplayError(Code, "DataWrite");
break;
}
/* Code > 0 */
Want2Tx -= Code;
TxBytes += (long)Code;
/* advance pointer */
Ptr += Code;
}
/* display transmitted bytes */
wsprintf((LPSTR)Temp,"%ld\r",TxBytes);
DisplayString((LPSTR)Temp);
}
/* no more data to send */
wsprintf((LPSTR)Temp,"[END] %ld bytes sent", TxBytes);
DisplayLine((LPSTR)Temp);
_lclose(FileHandle);
/* close the data socket */
MessageBeep(MB_ICONEXCLAMATION);
/* close listener & data socket */
wilCloseSocket(DataSock);
wilCloseSocket(ListenSock);
if(++DataPort>LAST_DATA_PORT) DataPort = FIRST_DATA_PORT;
/* any more control socket response ? */
GetControlIncoming();
POST_MSG(FTP_CMD_SUCCESS);
} /* end-switch(wParam) */
break;
case WM_CHAR:
/* user has typed character */
if(wParam==CR)
{/* do the CR */
DisplayChar((char)wParam);
/* user has completed input */
ConnectedMenuState();
DestroyCaret();
DisplayChar(LF);
InBuffer[InBufLen] = '\0';
/* execute command */
switch(InBufCmd)
{case MSG_FTP_CWD:
/* change working directory */
InBufCmd = 0;
wsprintf((LPSTR)Temp,"CWD %s",(LPSTR)InBuffer);
if(!StillConnected()) break;
AsyncCommand((LPSTR)Temp, FTP_CMD_SUCCESS, FTP_CMD_FAILURE,
ASYNC_MULTIPLE_CODED);
break;
case MSG_FTP_CONNECT:
/* connect to remote host */
InBufCmd = 0;
DoingCmdMenuState();
/* check FTP host name */
if( lstrlen((LPSTR)InBuffer) == 0)
{DisplayLine("Missing FTP address");
NotConnectedMenuState();
break;
}
DisplayString("Connecting to ");
DisplayLine((LPSTR)InBuffer);
SetCursor(WaitCursor);
/* connect to server */
ControlSock = AsyncConnect(hMainWnd,"FTP",(LPSTR)InBuffer,
FTP_PORT, FTP_CONN_SUCCESS,
FTP_CONN_FAILURE, ASYNC_MULTIPLE_CODED);
if((int)ControlSock<0)
DisplayLine("Control socket error");
/* get local address if don't already have it */
if( MyHostAddr == 0)
MyHostAddr = GetAddrFromSock(ControlSock, (LPSTR)MyDottedAddr);
break;
case MSG_FTP_GET:
/* get (receive) file */
DoingCmdMenuState();
InBufCmd = 0;
/* got filename ? */
if(*InBuffer=='\0')
{DisplayLine("Missing filename...");
break;
}
lstrcpy((LPSTR)Filename, (LPSTR)InBuffer);
/* open file for write */
FileHandle = _lcreat(Filename,0);
if(FileHandle<0)
{wsprintf((LPSTR)Temp,"Cannot create '%s'", Filename);
DisplayLine((LPSTR)Temp);
break;
}
if(StillConnected()) POST_MSG(FTP_GET_BEGIN);
break;
case MSG_FTP_PUT:
/* put (send) file */
DoingCmdMenuState();
InBufCmd = 0;
/* got filename ? */
if(*InBuffer=='\0')
{DisplayLine("Missing filename...");
break;
}
lstrcpy((LPSTR)Filename, (LPSTR)InBuffer);
/* open file for read */
FileHandle = _lopen(Filename,OF_READ|OF_SHARE_DENY_WRITE);
if(FileHandle<0)
{wsprintf((LPSTR)Temp,"Cannot open '%s'", Filename);
DisplayLine((LPSTR)Temp);
break;
}
if(StillConnected()) POST_MSG(FTP_PUT_BEGIN);
break;
default:
break;
} /* end-switch(InBufCmd) */
ConnectedMenuState();
*InBuffer = '\0';
} /* end-if(wParam==CR) */
else Add2Buffer((char)wParam);
break;
default:
return (DefWindowProc(hMainWnd, iMsg, wParam, lParam));
}
return 0;
} /* end MainWndProc */